<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\command;

use app\enum\KsAdvertiserDailyStatEnum;
use app\model\ClientAccountModel;
use app\model\ClientAccountOperationModel;
use app\model\OeAdvertiserDailyStatModel;
use app\model\ProjectAccountModel;
use think\console\Command;
use think\console\Input;
use think\console\Output;

class OeAdvertiserStaffProjectWork extends Command
{
    protected function configure()
    {
        // 指令配置
        $this->setName('oe_advertiser_staff_project_work')
            ->setDescription('更新_oe账户日流水_运营项目id');
    }

    protected function execute(Input $input, Output $output)
    {
        set_time_limit(0);
        ini_set('memory_limit', '-1');
        $output->writeln('=======巨量引擎-更新_oe账户日流水_运营id开始' . date('Y-m-d H:i:s', time()) . '=======');

        try {
            $page = $maxId = 0;
            while (true) {
                // 更新日流水运营id
                $advertiserDailyStatData = $this->_getAdvertiserDailyStatData($maxId, KsAdvertiserDailyStatEnum::TYPE_STAFF);
                if (empty($advertiserDailyStatData)) {
                    break;
                }
                // 运营人员id
                $advertiserIds = array_column($advertiserDailyStatData, 'advertiser_id');

                $staffData = $this->_getStaffData($advertiserIds);
                if (empty($staffData)) {
                    break;
                }
                $staffData = array_column($staffData, null, 'advertiser_id');

                foreach ($advertiserDailyStatData as $advertiserDailyStatDatum) {
                    if (! isset($staffData[$advertiserDailyStatDatum['advertiser_id']])) {
                        continue;
                    }
                    $this->_modifyStaffProjectId($advertiserDailyStatDatum['advertiser_id'], [
                        'staff_id' => $staffData[$advertiserDailyStatDatum['advertiser_id']]['staff_id'],
                    ]);
                }

                // 更新日流水项目id
                $advertiserDailyStatData = $this->_getAdvertiserDailyStatData($maxId, KsAdvertiserDailyStatEnum::TYPE_PROJECT);
                if (empty($advertiserDailyStatData)) {
                    break;
                }

                $advertiserIds = array_column($advertiserDailyStatData, 'advertiser_id');

                // 获取账号
                $clientAccountData = $this->_getClientAccountData($advertiserIds);
                if (empty($clientAccountData)) {
                    break;
                }

                // 获取项目
                $accountIds = array_column($clientAccountData, 'id');
                $projectAccountData = $this->_getProjectAccountData($accountIds);
                if (empty($projectAccountData)) {
                    break;
                }

                $clientAccountData = array_column($clientAccountData, null, 'advertiser_id');
                $projectAccountData = array_column($projectAccountData, null, 'account_id');

                foreach ($advertiserDailyStatData as $advertiserDailyStatDatum) {
                    if (! isset($clientAccountData[$advertiserDailyStatDatum['advertiser_id']])) {
                        continue;
                    }

                    $id = $clientAccountData[$advertiserDailyStatDatum['advertiser_id']]['id'];
                    if (! isset($projectAccountData[$id])) {
                        continue;
                    }

                    $this->_modifyStaffProjectId($advertiserDailyStatDatum['advertiser_id'], [
                        'project_id' => $projectAccountData[$id]['project_id'],
                    ]);
                }

                $maxId = end($advertiserDailyStatData)['id'];
                ++$page;

                $output->writeln('=======巨量引擎-更新_oe账户日流水_运营id第' . $page . '页结束,当前执行id:' . $maxId . '  ' . date('Y-m-d H:i:s', time()) . '=======');
            }
            $output->writeln('=======巨量引擎-更新_oe账户日流水_运营id结束' . date('Y-m-d H:i:s', time()) . '=======');
            $output->writeln('success');
        } catch (\Exception $e) {
            $output->writeln('=======巨量引擎-更新_oe账户日流水_运营id失败' . $e->getMessage() . '=======');
            $output->writeln('error');
        }
    }

    /**
     * 获取磁力引擎-账户日流水.
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function _getAdvertiserDailyStatData(int $maxId = 0, int $type = 1): array
    {
        $where = [];
        if ($maxId > 0) {
            $where[] = ['id', '>', $maxId];
        }
        if ($type == KsAdvertiserDailyStatEnum::TYPE_STAFF) {
            $where[] = ['staff_id', '=', KsAdvertiserDailyStatEnum::SCRIPT_STATUS];
        } else {
            $where[] = ['project_id', '=', KsAdvertiserDailyStatEnum::SCRIPT_STATUS];
        }

        return OeAdvertiserDailyStatModel::where($where)->limit(KsAdvertiserDailyStatEnum::SCRIPT_NUM)->field(true)->select()->toArray();
    }

    /**
     * 获取运营者数据.
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function _getStaffData($advertiserIds): array
    {
        return ClientAccountOperationModel::whereIn('advertiser_id', $advertiserIds)->field(true)->select()->toArray();
    }

    /**
     * 获取客户端账号数据.
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function _getClientAccountData($advertiserIds): array
    {
        return ClientAccountModel::whereIn('advertiser_id', $advertiserIds)->field(true)->select()->toArray();
    }

    private function _getProjectAccountData($accountIds): array
    {
        return ProjectAccountModel::whereIn('account_id', $accountIds)->field(true)->select()->toArray();
    }

    /**
     * 修改流水运营id.
     * @return OeAdvertiserDailyStatModel
     */
    private function _modifyStaffProjectId($advertiserId, $data)
    {
        return OeAdvertiserDailyStatModel::where('advertiser_id', $advertiserId)->update($data);
    }
}
